package com.example.rbac5.demo.aops;

import com.example.rbac5.demo.annotations.HasPower;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author wuyunbin
 */
@Aspect
@Component
@Slf4j
public class DemoAop {

    @Autowired
    HttpServletRequest request;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Pointcut("@annotation(com.example.rbac5.demo.annotations.HasPower)")
    public void pt(){}


    @Around("pt()")
    public Object handle(ProceedingJoinPoint pjp) throws Throwable {
        log.info("切中了");
        String userId = request.getHeader("Authorization");

        /*
        v1:
        userId->roleId->powerList->被请求的方法需要的权限表达式是否包含在我的powerList中？
        -> 是：放行
        -> 否：报错
        v2:被请求的方法需要的权限表达式是否包含在我的powerList中？
        powerList->读redis就行
        被请求的方法需要的权限表达式->读注解？ -> 1：获取方法->注解->表达式？  2：反射？
         */
        Signature signature = pjp.getSignature();
        //todo 转型
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        HasPower annotation = method.getAnnotation(HasPower.class);
        String express = annotation.value();

        //读取redis里面预存的权限列表
        String powerList= redisTemplate.opsForValue().get("powerList:"+userId);

        //判断powerList里面是否包含被请求的方法需要的权限表达式
        if(powerList.contains(express)){
            Object proceed = pjp.proceed();
            return proceed;
        }

        throw new RuntimeException("权限不足");

    }
}
